package com.spic.business.qrcode.service;

import com.alibaba.fastjson.JSON;
import com.spic.business.common.core.utils.ImageUtil;
import com.spic.business.informatization.befor_work_sign.domain.MeetingBeforeSignSubtable;
import com.spic.business.informatization.befor_work_sign.service.IMeetingBeforeSignSubtableService;
import com.spic.business.informatization.before_after_work.domain.MeetingBeforeAfter;
import com.spic.business.informatization.before_after_work.service.IMeetingBeforeAfterService;
import com.spic.business.mountguard.domain.MountSign;
import com.spic.business.mountguard.domain.MountSignRecord;
import com.spic.business.mountguard.service.IMountSignRecordService;
import com.spic.business.mountguard.service.IMountSignService;
import com.spic.business.mountguard.util.distanceUtil;
import com.spic.business.qrcode.domain.GuestCodeKey;
import com.spic.business.qrcode.domain.LinkResult;
import com.spic.business.qrcode.domain.QRCodeResult;
import com.spic.business.safetyactivity.domain.SafetyActivitySign;
import com.spic.business.safetyactivity.service.ISafetyActivitySignService;
import com.spic.business.train.trainInfo.domain.TrainInfo;
import com.spic.business.train.trainInfo.service.ITrainInfoService;
import com.spic.business.train.trainSign.domain.TrainSign;
import com.spic.business.train.trainSign.service.ITrainSignService;
import com.spic.common.core.constant.Constants;
import com.spic.common.core.text.UUID;
import com.spic.common.core.utils.DateUtils;
import com.spic.common.core.utils.SecurityUtils;
import com.spic.common.core.utils.SpringUtils;
import com.spic.common.core.utils.StringUtils;
import com.spic.common.core.web.domain.AjaxResult;
import com.spic.common.redis.service.RedisService;
import com.spic.system.api.RemoteUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author 290512
 * @create 2021-11-26 10:09
 */
@Service
public class QrService
{
    @Autowired
    private ITrainSignService trainSignService;
    @Autowired
    private ITrainInfoService trainInfoService;
    @Autowired
    private IMountSignService mountSignService;
    @Autowired
    private IMountSignRecordService mountSignRecordService;

    @Autowired
    private IMeetingBeforeSignSubtableService meetingBeforeSignSubtableService;

    @Autowired
    private IMeetingBeforeAfterService meetingBeforeAfterService;

    @Autowired
    private GuestCodeKeyService guestCodeKeyService;

    @Autowired
    private RemoteUserService remoteUserService;
    @Autowired
    private ISafetyActivitySignService safetyActivitySignService;

    private static final Logger log = LoggerFactory.getLogger(QrService.class);


    //通用生成二维码 固定时长 3分钟失效
    public QRCodeResult createAPPLink(QRCodeResult qrCodeResult)
    {
        QRCodeResult result = new QRCodeResult();
        String id = qrCodeResult.getId(); //业务id
        String type = qrCodeResult.getType(); // 类型 0 上岗签到  1 培训签到 2 班前会  3 班后会
        Long timeOut = null;
        if(StringUtils.isEmpty(id)|| StringUtils.isEmpty(type)){
            return result;
        }
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        String key = ""; //redis使用
        LinkResult linkResult = new LinkResult();
        if(type.equals("2") || type.equals("3")){ //班前会 班后会 特殊处理
            timeOut = 180L;
            uuid = id;
            key = uuid+type;
            linkResult.setId(id);
            linkResult.setKey(uuid+type);
            linkResult.setType(type);
            linkResult.setDeptId(Long.valueOf(SecurityUtils.getDeptId()));

        }else if(type.equals("0")){ //上岗签到  培训签到
            key = uuid;
            linkResult.setId(id);
            linkResult.setKey(key);
            linkResult.setType(type);
        }else if("1".equals(type)){ //培训签到
            timeOut = 3L;
            key = uuid;
            linkResult.setId(id);
            linkResult.setKey(key);
            linkResult.setType(type);
        }else if("4".equals(type)){ //访客管理
            List<GuestCodeKey> guestCodeKeys = guestCodeKeyService.guestCodeKeysList();
            if(guestCodeKeys!=null && guestCodeKeys.size()>0){
                key = guestCodeKeys.get(0).getRedisKey();
            }
            String link = createAPPLink();
            SpringUtils.getBean(RedisService.class).setCacheObject(key,link);
            String binary = ImageUtil.creatRrCode(link, 200,200); //二维码
            result.setCode(binary);
            return result;

        }else if("5".equals(type) || "6".equals(type)) { //安全活动签到或补签
            timeOut = 3L;
            key = uuid;
            linkResult.setId(id);
            linkResult.setKey(key);
            linkResult.setType(type);
        }
        if(timeOut!=null){
            SpringUtils.getBean(RedisService.class).setCacheObject(key,key,timeOut, TimeUnit.MINUTES);
        }else{
            SpringUtils.getBean(RedisService.class).setCacheObject(key,key);
        }
        String binary = ImageUtil.creatRrCode(JSON.toJSON(linkResult).toString(), 200,200); //二维码
        result.setCode(binary);
        result.setCreateTime(new Date());
        result.setDuration("180"); //二维码时长  3分钟
        return result;
    }

    @Transactional
    public AjaxResult getQrCodeUrl(QRCodeResult qrCodeResult)
    {
        String id = qrCodeResult.getId(); //业务id
        String type = qrCodeResult.getType(); // 类型 0 上岗签到  1 培训签到
        String key = qrCodeResult.getKey(); //uuid
        String deptId = qrCodeResult.getDeptId()+"";
        // TODO 测试通过后放开
//        if(!"0".equals(type)){
//            if(StringUtils.isNotEmpty(key) && !selectQrCodeState(key)){
//                return AjaxResult.error("二维码已经过期");
//            }
//        }
        if("0".equals(type)){//上岗签到
            boolean switchValue = Boolean.valueOf(remoteUserService.selectConfigByKey("sign.switch.value").getMsg());
            //String link= MsgLinkEnum.MODULE_LIST.getValue()+MsgLinkEnum.DEPTID.getValue()+id+MsgLinkEnum.KEY.getValue()+key+MsgLinkEnum.TYPE.getValue()+type;
            //获取本次签到
            MountSign mountSign = mountSignService.selectMountSignById(id);
            //根据本次签到经纬度与用户传来经纬度计算距离
            if(switchValue){
                if(mountSign.getSignLongitude()==null && mountSign.getSignLatitude()==null){
                    return AjaxResult.error("签到范围不正确！");
                }
                double signDistance =  distanceUtil.GetDistance(mountSign.getSignLongitude(),mountSign.getSignLatitude(),qrCodeResult.getLongitude(),qrCodeResult.getLatitude());
                if (signDistance>mountSign.getSignScope() ){
                    return AjaxResult.error("您已超出签到距离！");
                }else {
                    MountSignRecord mountSignRecord = new MountSignRecord();
                    mountSignRecord.setSignId(id);
                    mountSignRecord.setUserId(SecurityUtils.getUserId());
                    mountSignRecord.setDeptId(Long.parseLong(SecurityUtils.getDeptId()));
                    mountSignRecord.setSignTime(DateUtils.getNowDate());
                    mountSignRecordService.insertMountSignRecord(mountSignRecord);
                    return AjaxResult.success("签到成功！");
                }
            }else{
                MountSignRecord mountSignRecord = new MountSignRecord();
                mountSignRecord.setSignId(id);
                mountSignRecord.setUserId(SecurityUtils.getUserId());
                mountSignRecord.setDeptId(Long.parseLong(SecurityUtils.getDeptId()));
                mountSignRecord.setSignTime(DateUtils.getNowDate());
                mountSignRecordService.insertMountSignRecord(mountSignRecord);
                return AjaxResult.success("签到成功！");
            }

        }else if("1".equals(type)){ //培训签到
            TrainSign trainSign = new TrainSign();
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            trainSign.setTrainId(id);
            trainSign.setId(uuid);
            trainSign.setUserId(SecurityUtils.getUserId());
            int i = trainSignService.insertTrainSign(trainSign);
            if(i>0){
                TrainInfo trainInfo=trainInfoService.selectTrainInfoById(id);
                return AjaxResult.success(trainInfo.getTrainPlan().getTrainName()+"方案的"+trainInfo.getTrainPlanShift().getClassName()+"班次，"+SecurityUtils.getUsername()+"签到成功");
            }else{
                return AjaxResult.error("非本次培训人员");
            }
        }else if("2".equals(type) || "3".equals(type)){ //班前会签到
            if(StringUtils.isNull(deptId) || StringUtils.isNull(SecurityUtils.getDeptId())){
                return AjaxResult.success("用户信息获取失败，请重新登录");
            }
            if(!deptId.equals(SecurityUtils.getDeptId())){
                return AjaxResult.success("您不在本班组，签到失败");
            }
            MeetingBeforeSignSubtable meetingBeforeSignSubtable = new MeetingBeforeSignSubtable();
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            if("2".equals(type)){
                meetingBeforeSignSubtable.setType("1");
            }else {
                meetingBeforeSignSubtable.setType("2");
            }
            meetingBeforeSignSubtable.setParentId(id);
            meetingBeforeSignSubtable.setSignName(SecurityUtils.getUserId()+"");

            List<MeetingBeforeSignSubtable> meetingBeforeSignSubtables = meetingBeforeSignSubtableService.selectMeetingBeforeSignSubtableList(meetingBeforeSignSubtable);
            if(meetingBeforeSignSubtables!=null&& meetingBeforeSignSubtables.size()>0){
                return AjaxResult.success("你今天已经签到了!");
            }
            meetingBeforeSignSubtable.setId(uuid);
            meetingBeforeSignSubtable.setSignTime(new Date());
            meetingBeforeSignSubtable.setWhetherDrinking("N");
            meetingBeforeSignSubtableService.insertMeetingBeforeSignSubtable(meetingBeforeSignSubtable);
            //更新班前班后表的签到数据
            MeetingBeforeAfter meetingBeforeAfter = meetingBeforeAfterService.selectMeetingBeforeAfterById(id);
            Integer teamNumber = meetingBeforeAfter.getTeamNumber();
            //班前会
            if("2".equals(type)){
                meetingBeforeAfter.setAttendanceNumber(meetingBeforeAfter.getAttendanceNumber() + 1);
                meetingBeforeAfter.setAbsenteeismNumber(teamNumber - meetingBeforeAfter.getAttendanceNumber());
            }else {
                meetingBeforeAfter.setAttendanceNumberAfter(meetingBeforeAfter.getAttendanceNumberAfter() + 1);
                meetingBeforeAfter.setAbsenteeismNumberAfter(teamNumber - meetingBeforeAfter.getAttendanceNumberAfter());
            }
            meetingBeforeAfterService.updateMeetingBeforeAfter(meetingBeforeAfter);
            return AjaxResult.success("签到成功！");
        } else if ("5".equals(type) || "6".equals(type)) {
            if(StringUtils.isNull(SecurityUtils.getUserId())) {
                return AjaxResult.success("用户信息获取失败，请重新登录");
            }
            SafetyActivitySign safetyActivitySign = new SafetyActivitySign();
            safetyActivitySign.setActivityId(id);
            if("5".equals(type)) {
                safetyActivitySign.setType("1");
            } else {
                safetyActivitySign.setType("2");
            }
            safetyActivitySignService.insertSafetyActivitySign(safetyActivitySign);
        }
        return AjaxResult.success();
    }
    //设置二维码缓存时间  3分钟过期后二维码链接失效
    public boolean selectQrCodeState(String key)
    {
        Boolean state = SpringUtils.getBean(RedisService.class).hasKey(key);
        return state;
    }

    //二维码链接
    private String createAPPLink()
    {
        String linkIp ="";
        List<GuestCodeKey> guestCodeKeys = guestCodeKeyService.guestCodeKeysList();
        if(guestCodeKeys!=null && guestCodeKeys.size()>0){
            linkIp = guestCodeKeys.get(0).getLink();
        }
        return linkIp+"html/guestAdd2/index.html";
    }


    public static String urlEncode(String str)
    {
        try
        {
            return URLEncoder.encode(str, Constants.UTF8);
        }
        catch (UnsupportedEncodingException e)
        {
            return "";
        }
    }

    /**
     * 内容解码
     *
     * @param str 内容
     * @return 解码后的内容
     */
    public static String urlDecode(String str)
    {
        try
        {
            return URLDecoder.decode(str, Constants.UTF8);
        }
        catch (UnsupportedEncodingException e)
        {
            return "";
        }
    }

    public static void main(String[] args)
    {
        System.out.println(urlEncode("123"));
    }
}
